{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "use cuda\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "# %pip install pandas\n",
    "import pandas as pd\n",
    "\n",
    "USE_GPU = True\n",
    "dtype = torch.float32 # We will be using float throughout this tutorial.\n",
    "print_every = 100\n",
    "\n",
    "if USE_GPU and torch.cuda.is_available():\n",
    "    device = torch.device('cuda')\n",
    "    print(\"use cuda\")\n",
    "else:\n",
    "    device = torch.device('cpu')\n",
    "    print(\"use cpu\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           日期 期限品种  USD/CNY  EUR/CNY  100JPY/CNY  HKD/CNY  GBP/CNY  AUD/CNY  \\\n",
      "0  2024-10-11   3M   7.0196   7.7104      4.7822  0.90454   9.1627   4.7390   \n",
      "1  2024-10-10   3M   7.0124   7.7050      4.7598  0.90368   9.1670   4.7252   \n",
      "2  2024-10-09   3M   7.0118   7.7231      4.7899  0.90315   9.1764   4.7274   \n",
      "3  2024-10-08   3M   7.0131   7.7336      4.8014  0.90395   9.1813   4.7298   \n",
      "4  2024-09-30   3M   6.9582   7.7967      4.9514  0.89649   9.3074   4.8232   \n",
      "\n",
      "  NZD/CNY  SGD/CNY  ...  CNY/KRW  CNY/AED  CNY/SAR  CNY/HUF  CNY/PLN CNY/DKK  \\\n",
      "0  4.2869   5.4009  ...   190.80  0.52318  0.53559  52.4240  0.56197  0.9667   \n",
      "1  4.2746   5.3905  ...   191.17  0.52372  0.53614  52.1774  0.56118  0.9670   \n",
      "2  4.2748   5.4015  ...   190.25  0.52370  0.53609  52.1070  0.56131  0.9648   \n",
      "3  4.3026   5.4025  ...   191.16  0.52358  0.53616  52.3901  0.56316  0.9631   \n",
      "4  4.4316   5.4607  ...   186.76  0.52773  0.53974  51.3528  0.55137  0.9555   \n",
      "\n",
      "   CNY/SEK CNY/NOK CNY/MXN CNY/THB  \n",
      "0   1.4729  1.5286  2.8121  4.7258  \n",
      "1   1.4749  1.5343  2.8145  4.7527  \n",
      "2   1.4673  1.5294  2.8020  4.7267  \n",
      "3   1.4691  1.5187  2.7951  4.7635  \n",
      "4   1.4431  1.5090  2.8708  4.6111  \n",
      "\n",
      "[5 rows x 24 columns]\n"
     ]
    }
   ],
   "source": [
    "# %pip install openpyxl\n",
    "from datetime import datetime, timedelta\n",
    "\n",
    "df = pd.read_excel('rate18-24.xlsx')\n",
    "df = df.drop('CNY/TRY', axis=1)\n",
    "df = df.drop('CNY/MOP', axis=1)\n",
    "df = df.drop('CNY/RUB', axis=1)\n",
    "print(df.head()) \n",
    "\n",
    "titles = df.columns\n",
    "data_without_titles = df.values\n",
    "raw_data=list(data_without_titles)\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_invalid(el):\n",
    "    return el is None or el==\"---\"\n",
    "\n",
    "def clean_data(raw_data):\n",
    "    for i in range(len(raw_data)):\n",
    "        for j in range(2, len(raw_data[0])):\n",
    "            if is_invalid(raw_data[i][j]):\n",
    "                last, next = None, None\n",
    "                for k in range(i-1, -1, -1):\n",
    "                    if not is_invalid(raw_data[k][j]):\n",
    "                        next=raw_data[k][j]\n",
    "                for k in range(i+1, len(raw_data)):\n",
    "                    if not is_invalid(raw_data[k][j]):\n",
    "                        last=raw_data[k][j]\n",
    "\n",
    "                if last==None and next==None:\n",
    "                    # raw_data[i][j] = \"0\"\n",
    "                    raise Exception(\"last==None and next==None\")\n",
    "                elif last==None:\n",
    "                    raw_data[i][j]=next\n",
    "                elif next==None:\n",
    "                    raw_data[i][j]=last\n",
    "                else:\n",
    "                    raw_data[i][j]=str((float(last)+float(next))/2) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_nextdays_x(raw_data, now_row, next_days_num):\n",
    "    now_date = raw_data[now_row][0]\n",
    "    now_date_obj = datetime.strptime(now_date, \"%Y-%m-%d\")\n",
    "    next_dates_obj = now_date_obj + timedelta(days=next_days_num)\n",
    "    next_date = next_dates_obj.strftime(\"%Y-%m-%d\")\n",
    "    i=now_row\n",
    "    while i>=0:\n",
    "        if raw_data[i][0]>=next_date:\n",
    "            return [float(item) for item in raw_data[i][2:]]\n",
    "        i-=1\n",
    "\n",
    "    return None\n",
    "\n",
    "\n",
    "def make_datas(raw_data):\n",
    "    row_num, column_num = len(raw_data), len(raw_data[0])\n",
    "    concurr_num = column_num-2\n",
    "\n",
    "    r=row_num-1\n",
    "    dayn=60 # 每n个工作日的数据估计下一个月的涨幅\n",
    "    period = 30\n",
    "    Xs, ys = [], []\n",
    "    while r>=0:\n",
    "        x = []\n",
    "        buy_day_x=[]\n",
    "        r_now=r\n",
    "        for i in range(dayn):\n",
    "            r_now-=1\n",
    "            for c in range(2, column_num):\n",
    "                x.append(float(raw_data[r_now][c]))\n",
    "                if i==dayn-1:\n",
    "                    buy_day_x.append(raw_data[r_now][c])\n",
    "\n",
    "        sell_day_x=find_nextdays_x(raw_data, r_now, period)\n",
    "        if sell_day_x is None:\n",
    "            break\n",
    "        y = [(float(sell_day_x[i])-float(buy_day_x[i])) / float(buy_day_x[i]) for i in range(concurr_num)]\n",
    "        Xs.append(x)\n",
    "        ys.append(y)\n",
    "        r-=1\n",
    "    \n",
    "    return Xs, ys\n",
    "\n",
    "def make_today_x(raw_data, dayn):\n",
    "    today = raw_data[0][0]\n",
    "    print(\"latest date is \", today)\n",
    "    # today_obj = datetime.strptime(today, \"%Y-%m-%d\")\n",
    "    # last_date_obj = today_obj + timedelta(days=dayn)\n",
    "    last_date_row = dayn-1\n",
    "\n",
    "    x=[]\n",
    "    for i in range(last_date_row, -1, -1):\n",
    "        for item in raw_data[i][2:]:\n",
    "            x.append(float(item))\n",
    "\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "latest date is  2024-10-11\n",
      "1320\n"
     ]
    }
   ],
   "source": [
    "clean_data(raw_data)\n",
    "X_train, y_train = make_datas(raw_data)\n",
    "# print(X_train, y_train)\n",
    "# print(len(X_train),len(X_train[0]), X_train[:5])\n",
    "# print(len(y_train),len(y_train[0]), y_train[:5])\n",
    "\n",
    "today_x=make_today_x(raw_data, 60)\n",
    "print(len(today_x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 读今天的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           日期 期限品种  USD/CNY  EUR/CNY  100JPY/CNY  HKD/CNY  GBP/CNY  AUD/CNY  \\\n",
      "0  2024-10-15   3M   7.0584   7.7265      4.7760  0.90992   9.2196   4.7546   \n",
      "1  2024-10-14   3M   7.0237   7.7077      4.7637  0.90517   9.1720   4.7419   \n",
      "2  2024-10-11   3M   7.0196   7.7104      4.7822  0.90454   9.1627   4.7390   \n",
      "3  2024-10-10   3M   7.0124   7.7050      4.7598  0.90368   9.1670   4.7252   \n",
      "4  2024-10-09   3M   7.0118   7.7231      4.7899  0.90315   9.1764   4.7274   \n",
      "\n",
      "   NZD/CNY  SGD/CNY  ...  CNY/KRW  CNY/AED  CNY/SAR  CNY/HUF  CNY/PLN  \\\n",
      "0   4.3039   5.4155  ...   191.62  0.52026  0.53273  52.2937  0.55975   \n",
      "1   4.2873   5.4022  ...   192.10  0.52280  0.53516  52.5070  0.56089   \n",
      "2   4.2869   5.4009  ...   190.80  0.52318  0.53559  52.4240  0.56197   \n",
      "3   4.2746   5.3905  ...   191.17  0.52372  0.53614  52.1774  0.56118   \n",
      "4   4.2748   5.4015  ...   190.25  0.52370  0.53609  52.1070  0.56131   \n",
      "\n",
      "   CNY/DKK  CNY/SEK  CNY/NOK  CNY/MXN  CNY/THB  \n",
      "0   0.9647   1.4706   1.5300   2.7854   4.7004  \n",
      "1   0.9672   1.4704   1.5265   2.7880   4.7030  \n",
      "2   0.9667   1.4729   1.5286   2.8121   4.7258  \n",
      "3   0.9670   1.4749   1.5343   2.8145   4.7527  \n",
      "4   0.9648   1.4673   1.5294   2.8020   4.7267  \n",
      "\n",
      "[5 rows x 24 columns]\n",
      "latest date is  2024-10-15\n",
      "1320\n"
     ]
    }
   ],
   "source": [
    "df_tody = pd.read_excel('rate_today.xlsx')\n",
    "df_tody = df_tody.drop('CNY/TRY', axis=1)\n",
    "df_tody = df_tody.drop('CNY/MOP', axis=1)\n",
    "df_tody = df_tody.drop('CNY/RUB', axis=1)\n",
    "print(df_tody.head()) \n",
    "\n",
    "today_raw_data = list(df_tody.values)\n",
    "# print(today_raw_data)\n",
    "clean_data(today_raw_data)\n",
    "# print(today_raw_data)\n",
    "today_x=make_today_x(today_raw_data, 60)\n",
    "print(len(today_x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def flatten(x):\n",
    "    N = x.shape[0] # read in N, C, H, W\n",
    "    return x.view(N, -1)  # \"flatten\" the C * H * W values into a single vector per image\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TwoLayerFC(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, num_classes):\n",
    "        super().__init__()\n",
    "        # assign layer objects to class attributes\n",
    "        self.fc1 = nn.Linear(input_size, hidden_size)\n",
    "        nn.init.kaiming_normal_(self.fc1.weight)\n",
    "        \n",
    "        self.fc2 = nn.Linear(hidden_size, hidden_size*2)\n",
    "        nn.init.kaiming_normal_(self.fc2.weight)\n",
    "        \n",
    "        self.fc3 = nn.Linear(hidden_size*2, hidden_size)\n",
    "        nn.init.kaiming_normal_(self.fc3.weight)\n",
    "        \n",
    "        self.fc4 = nn.Linear(hidden_size, hidden_size*2)\n",
    "        nn.init.kaiming_normal_(self.fc4.weight)\n",
    "\n",
    "        self.fc5 = nn.Linear(hidden_size*2, hidden_size//2)\n",
    "        nn.init.kaiming_normal_(self.fc5.weight)\n",
    "\n",
    "        self.fc6 = nn.Linear(hidden_size//2, hidden_size*3)\n",
    "        nn.init.kaiming_normal_(self.fc6.weight)\n",
    "\n",
    "        self.fc7 = nn.Linear(hidden_size*3, hidden_size)\n",
    "        nn.init.kaiming_normal_(self.fc7.weight)\n",
    "\n",
    "        self.fc8 = nn.Linear(hidden_size, num_classes)\n",
    "        nn.init.kaiming_normal_(self.fc8.weight)\n",
    "\n",
    "    \n",
    "    def forward(self, x):\n",
    "        # forward always defines connectivity\n",
    "        x = flatten(x)\n",
    "        x1= F.dropout(F.relu(self.fc1(x)), 0.5)\n",
    "        x2= F.dropout(F.relu(self.fc2(x1)), 0.5)\n",
    "        x3= F.dropout(self.fc3(x2))\n",
    "        x4= F.dropout(F.relu(self.fc4(x3))+x2, 0.5)\n",
    "        x5= F.dropout(self.fc5(x4), 0.6)\n",
    "        x6= F.dropout(self.fc6(x5), 0.5)\n",
    "        x7= self.fc7(x6)\n",
    "        x8= self.fc8(x7)\n",
    "        scores = x8\n",
    "\n",
    "        return scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([64, 10])\n"
     ]
    }
   ],
   "source": [
    "def test_TwoLayerFC():\n",
    "    input_size = 50\n",
    "    x = torch.zeros((64, input_size), dtype=dtype)  # minibatch size 64, feature dimension 50\n",
    "    model = TwoLayerFC(input_size, 42, 10)\n",
    "    scores = model(x)\n",
    "    print(scores.size())  # you should see [64, 10]\n",
    "test_TwoLayerFC()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "learning_rate = 1e-4\n",
    "model = TwoLayerFC(len(X_train[0]), 5120, len(y_train[0]))\n",
    "optimizer = optim.SGD(model.parameters(), lr=learning_rate,\n",
    "                     momentum=0.9, nesterov=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def check_accuracy_part34(loader, model):\n",
    "    if loader.dataset.train:\n",
    "        print('Checking accuracy on validation set')\n",
    "    else:\n",
    "        print('Checking accuracy on test set')   \n",
    "    num_correct05 = 0\n",
    "    num_correct1 = 0\n",
    "    num_correct2 = 0\n",
    "    num_samples = 0\n",
    "    model.eval()  # set model to evaluation mode\n",
    "    with torch.no_grad():\n",
    "        for x, y in loader:\n",
    "            x = x.to(device=device, dtype=dtype)  # move to device, e.g. GPU\n",
    "            y = y.to(device=device, dtype=dtype)\n",
    "            scores = model(x)\n",
    "            num_correct05 += ((scores - y).abs()<0.5).sum()\n",
    "            num_correct1 += ((scores - y).abs()<1).sum()\n",
    "            num_correct2 += ((scores - y).abs()<2).sum()\n",
    "            num_samples += scores.size(0)*scores.size(1)\n",
    "        acc05 = float(num_correct05) / num_samples\n",
    "        acc1 = float(num_correct1) / num_samples\n",
    "        acc2 = float(num_correct2) / num_samples\n",
    "        print('acc<(0.5,1,2) Got (%d / %d, %d / %d, %d / %d) correct (%.2f, %.2f, %.2f)' % (num_correct05, num_samples, num_correct1, num_samples, num_correct2, num_samples, 100 * acc05, 100 * acc1, 100 * acc2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "class CustomDataset(Dataset):\n",
    "    def __init__(self, data, labels,train=True):\n",
    "        self.data = data\n",
    "        self.labels = labels\n",
    "        self.train = train\n",
    " \n",
    "    def __len__(self):\n",
    "        return len(self.data)\n",
    " \n",
    "    def __getitem__(self, idx):\n",
    "        return torch.tensor(self.data[idx], requires_grad=True), torch.tensor(self.labels[idx], requires_grad=True)*100\n",
    "train_num=int(len(X_train)*0.8)\n",
    "dataset1 = CustomDataset(X_train[:train_num], y_train[:train_num], train=True)\n",
    "dataset2 = CustomDataset(X_train[train_num:], y_train[train_num:], train=False)\n",
    "\n",
    "loader_train = DataLoader(dataset1, batch_size=512, shuffle=True, num_workers=0)\n",
    "loader_val = DataLoader(dataset2, batch_size=128, shuffle=True, num_workers=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Start trainning...\n",
      "Iteration 0, loss = 1072.0746\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (0 / 6204, 1 / 6204, 2 / 6204) correct (0.00, 0.02, 0.03)\n",
      "\n",
      "Iteration 100, loss = 1.9256\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1680 / 6204, 2967 / 6204, 4659 / 6204) correct (27.08, 47.82, 75.10)\n",
      "\n",
      "Iteration 200, loss = 1.8567\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1707 / 6204, 2988 / 6204, 4656 / 6204) correct (27.51, 48.16, 75.05)\n",
      "\n",
      "Iteration 300, loss = 1.9204\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1722 / 6204, 2962 / 6204, 4682 / 6204) correct (27.76, 47.74, 75.47)\n",
      "\n",
      "Iteration 400, loss = 1.8911\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1727 / 6204, 3011 / 6204, 4684 / 6204) correct (27.84, 48.53, 75.50)\n",
      "\n",
      "Iteration 500, loss = 1.9430\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1739 / 6204, 3001 / 6204, 4708 / 6204) correct (28.03, 48.37, 75.89)\n",
      "\n",
      "Iteration 600, loss = 1.8823\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1740 / 6204, 3040 / 6204, 4694 / 6204) correct (28.05, 49.00, 75.66)\n",
      "\n",
      "Iteration 700, loss = 1.8633\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1709 / 6204, 3059 / 6204, 4711 / 6204) correct (27.55, 49.31, 75.93)\n",
      "\n",
      "Iteration 800, loss = 1.8273\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1755 / 6204, 3034 / 6204, 4707 / 6204) correct (28.29, 48.90, 75.87)\n",
      "\n",
      "Iteration 900, loss = 1.7579\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1734 / 6204, 3012 / 6204, 4705 / 6204) correct (27.95, 48.55, 75.84)\n",
      "\n",
      "Iteration 1000, loss = 1.6998\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1759 / 6204, 3031 / 6204, 4704 / 6204) correct (28.35, 48.86, 75.82)\n",
      "\n",
      "Iteration 1100, loss = 1.7970\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1776 / 6204, 3056 / 6204, 4724 / 6204) correct (28.63, 49.26, 76.14)\n",
      "\n",
      "Iteration 1200, loss = 1.9489\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1761 / 6204, 3068 / 6204, 4716 / 6204) correct (28.38, 49.45, 76.02)\n",
      "\n",
      "Iteration 1300, loss = 1.9990\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1770 / 6204, 3020 / 6204, 4723 / 6204) correct (28.53, 48.68, 76.13)\n",
      "\n",
      "Iteration 1400, loss = 2.1077\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1765 / 6204, 3061 / 6204, 4697 / 6204) correct (28.45, 49.34, 75.71)\n",
      "\n",
      "Iteration 1500, loss = 1.9567\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1782 / 6204, 3072 / 6204, 4736 / 6204) correct (28.72, 49.52, 76.34)\n",
      "\n",
      "Iteration 1600, loss = 1.9576\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1758 / 6204, 3076 / 6204, 4738 / 6204) correct (28.34, 49.58, 76.37)\n",
      "\n",
      "Iteration 1700, loss = 1.8483\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1778 / 6204, 3033 / 6204, 4714 / 6204) correct (28.66, 48.89, 75.98)\n",
      "\n",
      "Iteration 1800, loss = 1.7173\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1789 / 6204, 3048 / 6204, 4713 / 6204) correct (28.84, 49.13, 75.97)\n",
      "\n",
      "Iteration 1900, loss = 1.7610\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1749 / 6204, 3060 / 6204, 4727 / 6204) correct (28.19, 49.32, 76.19)\n",
      "\n",
      "Iteration 2000, loss = 1.9180\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1771 / 6204, 3028 / 6204, 4727 / 6204) correct (28.55, 48.81, 76.19)\n",
      "\n",
      "Iteration 2100, loss = 1.9668\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1785 / 6204, 3048 / 6204, 4713 / 6204) correct (28.77, 49.13, 75.97)\n",
      "\n",
      "Iteration 2200, loss = 1.7376\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1769 / 6204, 3070 / 6204, 4732 / 6204) correct (28.51, 49.48, 76.27)\n",
      "\n",
      "Iteration 2300, loss = 2.0440\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1793 / 6204, 3057 / 6204, 4728 / 6204) correct (28.90, 49.27, 76.21)\n",
      "\n",
      "Iteration 2400, loss = 1.9488\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1785 / 6204, 3063 / 6204, 4723 / 6204) correct (28.77, 49.37, 76.13)\n",
      "\n",
      "Iteration 2500, loss = 1.9594\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1776 / 6204, 3042 / 6204, 4716 / 6204) correct (28.63, 49.03, 76.02)\n",
      "\n",
      "Iteration 2600, loss = 1.9016\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1807 / 6204, 3064 / 6204, 4714 / 6204) correct (29.13, 49.39, 75.98)\n",
      "\n",
      "Iteration 2700, loss = 1.8397\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1799 / 6204, 3073 / 6204, 4724 / 6204) correct (29.00, 49.53, 76.14)\n",
      "\n",
      "Iteration 2800, loss = 1.9008\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1800 / 6204, 3067 / 6204, 4732 / 6204) correct (29.01, 49.44, 76.27)\n",
      "\n",
      "Iteration 2900, loss = 1.8197\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1781 / 6204, 3051 / 6204, 4732 / 6204) correct (28.71, 49.18, 76.27)\n",
      "\n",
      "Iteration 3000, loss = 1.8584\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1777 / 6204, 3033 / 6204, 4731 / 6204) correct (28.64, 48.89, 76.26)\n",
      "\n",
      "Iteration 3100, loss = 1.9055\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1793 / 6204, 3053 / 6204, 4719 / 6204) correct (28.90, 49.21, 76.06)\n",
      "\n",
      "Iteration 3200, loss = 1.8974\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1786 / 6204, 3061 / 6204, 4740 / 6204) correct (28.79, 49.34, 76.40)\n",
      "\n",
      "Iteration 3300, loss = 1.9508\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1805 / 6204, 3070 / 6204, 4715 / 6204) correct (29.09, 49.48, 76.00)\n",
      "\n",
      "Iteration 3400, loss = 1.8752\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1779 / 6204, 3044 / 6204, 4721 / 6204) correct (28.68, 49.07, 76.10)\n",
      "\n",
      "Iteration 3500, loss = 1.9337\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1827 / 6204, 3066 / 6204, 4736 / 6204) correct (29.45, 49.42, 76.34)\n",
      "\n",
      "Iteration 3600, loss = 1.9087\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1794 / 6204, 3067 / 6204, 4730 / 6204) correct (28.92, 49.44, 76.24)\n",
      "\n",
      "Iteration 3700, loss = 1.8421\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1778 / 6204, 3061 / 6204, 4728 / 6204) correct (28.66, 49.34, 76.21)\n",
      "\n",
      "Iteration 3800, loss = 1.9575\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1785 / 6204, 3060 / 6204, 4721 / 6204) correct (28.77, 49.32, 76.10)\n",
      "\n",
      "Iteration 3900, loss = 1.8266\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1789 / 6204, 3065 / 6204, 4727 / 6204) correct (28.84, 49.40, 76.19)\n",
      "\n",
      "Iteration 4000, loss = 1.8364\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1786 / 6204, 3056 / 6204, 4722 / 6204) correct (28.79, 49.26, 76.11)\n",
      "\n",
      "Iteration 4100, loss = 1.9771\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1773 / 6204, 3055 / 6204, 4719 / 6204) correct (28.58, 49.24, 76.06)\n",
      "\n",
      "Iteration 4200, loss = 2.0201\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1774 / 6204, 3082 / 6204, 4734 / 6204) correct (28.59, 49.68, 76.31)\n",
      "\n",
      "Iteration 4300, loss = 1.9044\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1796 / 6204, 3066 / 6204, 4730 / 6204) correct (28.95, 49.42, 76.24)\n",
      "\n",
      "Iteration 4400, loss = 1.9133\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1777 / 6204, 3075 / 6204, 4725 / 6204) correct (28.64, 49.56, 76.16)\n",
      "\n",
      "Iteration 4500, loss = 1.8442\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1787 / 6204, 3074 / 6204, 4734 / 6204) correct (28.80, 49.55, 76.31)\n",
      "\n",
      "Iteration 4600, loss = 2.0135\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1784 / 6204, 3054 / 6204, 4737 / 6204) correct (28.76, 49.23, 76.35)\n",
      "\n",
      "Iteration 4700, loss = 1.8999\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1786 / 6204, 3065 / 6204, 4736 / 6204) correct (28.79, 49.40, 76.34)\n",
      "\n",
      "Iteration 4800, loss = 1.9373\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1794 / 6204, 3055 / 6204, 4732 / 6204) correct (28.92, 49.24, 76.27)\n",
      "\n",
      "Iteration 4900, loss = 1.8481\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1790 / 6204, 3072 / 6204, 4739 / 6204) correct (28.85, 49.52, 76.39)\n",
      "\n",
      "Iteration 5000, loss = 1.9227\n",
      "Checking accuracy on test set\n",
      "acc<(0.5,1,2) Got (1803 / 6204, 3060 / 6204, 4733 / 6204) correct (29.06, 49.32, 76.29)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(\"Start trainning...\")\n",
    "model = model.to(device=device)  # move the model parameters to CPU/GPU\n",
    "epochs = 2000\n",
    "\n",
    "for e in range(epochs+1):\n",
    "    for t, (x, y) in enumerate(loader_train):\n",
    "        model.train()  # put model to training mode\n",
    "        x = x.to(device=device, dtype=dtype)  # move to device, e.g. GPU\n",
    "        y = y.to(device=device, dtype=dtype)\n",
    "        scores = model(x)\n",
    "        loss = F.l1_loss(scores, y)\n",
    "\n",
    "        # Zero out all of the gradients for the variables which the optimizer\n",
    "        # will update.\n",
    "        optimizer.zero_grad()\n",
    "        # This is the backwards pass: compute the gradient of the loss with\n",
    "        # respect to each  parameter of the model.\n",
    "        loss.backward()\n",
    "        # Actually update the parameters of the model using the gradients\n",
    "        # computed by the backwards pass.\n",
    "        optimizer.step()\n",
    "\n",
    "    if e % print_every == 0:\n",
    "        print('Iteration %d, loss = %.4f' % (e, loss.item()))\n",
    "        check_accuracy_part34(loader_val, model)\n",
    "        print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "24 Index(['日期', '期限品种', 'USD/CNY', 'EUR/CNY', '100JPY/CNY', 'HKD/CNY', 'GBP/CNY',\n",
      "       'AUD/CNY', 'NZD/CNY', 'SGD/CNY', 'CHF/CNY', 'CAD/CNY', 'CNY/MYR',\n",
      "       'CNY/ZAR', 'CNY/KRW', 'CNY/AED', 'CNY/SAR', 'CNY/HUF', 'CNY/PLN',\n",
      "       'CNY/DKK', 'CNY/SEK', 'CNY/NOK', 'CNY/MXN', 'CNY/THB'],\n",
      "      dtype='object')\n",
      "torch.Size([1, 1320])\n",
      "tensor([-0.4425, -1.3246, -5.1584, -0.3130, -0.7893,  0.8491, -1.0616, -0.6859,\n",
      "        -1.8021, -1.5072, -0.7688, -1.8824,  0.8777,  0.4531,  0.5293,  2.4561,\n",
      "         1.9965,  1.3312,  0.7524, -0.3195, -2.7594, -0.1141], device='cuda:0')\n",
      "tensor([[-0.0222, -0.0608, -0.5008, -0.1427,  0.1079, -0.0518, -0.3195,  0.3653,\n",
      "          0.3124,  0.1724, -0.0218,  0.2090,  0.1243,  0.0115,  0.1027,  0.4494,\n",
      "          0.2241,  0.0734,  0.1441,  0.1822, -0.5861, -0.1032]],\n",
      "       device='cuda:0')\n",
      "tensor([[ 0.4203,  1.2638,  4.6576,  0.1703,  0.8972, -0.9009,  0.7421,  1.0512,\n",
      "          2.1145,  1.6797,  0.7469,  2.0914, -0.7534, -0.4417, -0.4266, -2.0066,\n",
      "         -1.7724, -1.2578, -0.6083,  0.5017,  2.1734,  0.0109]],\n",
      "       device='cuda:0')\n"
     ]
    }
   ],
   "source": [
    "which = -1\n",
    "print(len(titles),titles)\n",
    "curr_xt, curr_y=torch.tensor([X_train[which]], dtype=dtype).to(device=device), (torch.tensor(y_train[which])*100).to(device=device)\n",
    "print(curr_xt.shape)\n",
    "print(curr_y)\n",
    "model.eval()  # set model to evaluation mode\n",
    "with torch.no_grad():\n",
    "    pred_y=model(curr_xt)\n",
    "    print(pred_y)\n",
    "    print(pred_y-curr_y)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.0446, -0.2233, -0.5062, -0.1654, -0.0554,  0.0958, -0.4735,  0.1325,\n",
      "          0.2447,  0.3040, -0.0955,  0.1964,  0.2413, -0.0740,  0.0478,  0.3330,\n",
      "          0.1554,  0.0222,  0.2717,  0.4378, -0.8063, -0.2676]],\n",
      "       device='cuda:0')\n"
     ]
    }
   ],
   "source": [
    "today_xt=torch.tensor([today_x], dtype=dtype).to(device=device)\n",
    "# print(today_x)\n",
    "model.eval()  # set model to evaluation mode\n",
    "with torch.no_grad():\n",
    "    pred_y=model(today_xt)\n",
    "    print(pred_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNY/ZAR\n"
     ]
    }
   ],
   "source": [
    "print(titles[13])\n",
    "#for i in range(len(today_x)):\n",
    "#    print(i, today_x[i],  X_train[which][i], today_x[i]- X_train[which][i])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.save({\n",
    "    'model_state_dict': model.state_dict(),\n",
    "    'optimizer_state_dict': optimizer.state_dict(),\n",
    "    'epoch': epochs,\n",
    "    'loss': loss\n",
    "}, 'model_checkpoint.pth.tar')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-0.1957,  0.0401, -0.3363, -0.1480, -0.0308,  0.0672, -0.3671, -0.0518,\n",
      "          0.1463,  0.1672,  0.0328,  0.2396,  0.2104,  0.1123,  0.1475,  0.4576,\n",
      "          0.2148, -0.0262,  0.1537,  0.2840, -0.6754, -0.1210]],\n",
      "       device='cuda:0')\n"
     ]
    }
   ],
   "source": [
    "checkpoint = torch.load('model_checkpoint.pth.tar', map_location=torch.device('cpu'))\n",
    "model.load_state_dict(checkpoint['model_state_dict'])\n",
    "optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n",
    "epoch = checkpoint['epoch']\n",
    "loss = checkpoint['loss']\n",
    "\n",
    "def test_checkpoint():\n",
    "    today_xt=torch.tensor([today_x], dtype=dtype).to(device=device)\n",
    "    model.eval()  # set model to evaluation mode\n",
    "    with torch.no_grad():\n",
    "        pred_y=model(today_xt)\n",
    "        print(pred_y)\n",
    "\n",
    "test_checkpoint()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
